import random
import cv2
import time
import math
import cvzone
from cvzone.HandTrackingModule import HandDetector
import pygame
import controller

def crebak(img, color, ptx, pty, w, h):
    alphaReserve = 0.6
    BChannel, GChannel, RChannel = color
    yMin, yMax = pty, pty + h
    xMin, xMax = ptx, ptx + w
    img[yMin:yMax, xMin:xMax, 0] = img[yMin:yMax, xMin:xMax, 0] * alphaReserve + BChannel * (1 - alphaReserve)
    img[yMin:yMax, xMin:xMax, 1] = img[yMin:yMax, xMin:xMax, 1] * alphaReserve + GChannel * (1 - alphaReserve)
    img[yMin:yMax, xMin:xMax, 2] = img[yMin:yMax, xMin:xMax, 2] * alphaReserve + RChannel * (1 - alphaReserve)

    line = 35
    cv2.rectangle(img, (ptx, pty), (ptx + w, pty + h), (255, 125, 255), 2)  # 边框

    return img


def gesture1(lmList):
    x = 11111
    d = math.sqrt((lmList[5][0] - lmList[17][0]) ** 2 + (lmList[5][1] - lmList[17][1]) ** 2 + (
            lmList[5][2] - lmList[17][2]) ** 2)
    ab = math.sqrt(
        (lmList[8][0] - lmList[4][0]) ** 2 + (lmList[8][1] - lmList[4][1]) ** 2 + (lmList[8][2] - lmList[4][2]) ** 2)
    bc = math.sqrt(
        (lmList[12][0] - lmList[8][0]) ** 2 + (lmList[12][1] - lmList[8][1]) ** 2 + (lmList[12][2] - lmList[8][2]) ** 2)
    de = math.sqrt(
        (lmList[16][0] - lmList[20][0]) ** 2 + (lmList[16][1] - lmList[20][1]) ** 2 + (
                lmList[16][2] - lmList[20][2]) ** 2)
    cd = math.sqrt(
        (lmList[16][0] - lmList[12][0]) ** 2 + (lmList[16][1] - lmList[12][1]) ** 2 + (
                lmList[16][2] - lmList[12][2]) ** 2)
    c = math.sqrt(
        (lmList[9][0] - lmList[12][0]) ** 2 + (lmList[9][1] - lmList[12][1]) ** 2 + (
                lmList[9][2] - lmList[12][2]) ** 2)
    ad = math.sqrt(
        (lmList[4][0] - lmList[16][0]) ** 2 + (lmList[4][1] - lmList[16][1]) ** 2 + (
                lmList[4][2] - lmList[16][2]) ** 2)
    if ab < d / 2 and bc > d / 2:
        x = 1  # ok
    elif de > d * 3 / 4 and bc > d and ab > d:
        x = 2  # spider
    elif de < d / 2 and c < 3 * d / 4 and ab > d and cd < d / 2:
        x = 3  # gun
    elif bc < d / 2 and c < 3 * d / 4 and de < d / 2:
        x = 4  # big
    elif ad < d / 2 and ab > 3 * d / 4 and de < d / 2:
        x = 5  # ye

    return x


def gesture2(lmList):
    d = math.sqrt(
        (lmList[5][0] - lmList[17][0]) ** 2 + (lmList[5][1] - lmList[17][1]) ** 2 + (lmList[5][2] - lmList[17][2]) ** 2)
    ab = math.sqrt(
        (lmList[8][0] - lmList[4][0]) ** 2 + (lmList[8][1] - lmList[4][1]) ** 2 + (lmList[8][2] - lmList[4][2]) ** 2)
    cd = math.sqrt((lmList[16][0] - lmList[12][0]) ** 2 + (lmList[16][1] - lmList[12][1]) ** 2 + (
            lmList[16][2] - lmList[12][2]) ** 2)
    q = math.sqrt((lmList[4][0] - lmList[10][0]) ** 2 + (lmList[4][1] - lmList[10][1]) ** 2 + (
            lmList[4][2] - lmList[10][2]) ** 2)
    if ab < d / 2 and cd < d / 2 and q < d / 2:
        return True
    return False
def game1():
    # （1）捕获摄像头
    cap = cv2.VideoCapture(0)
    cap.set(3, 1281)  # 读入的图像的宽
    cap.set(4, 720)  # 读入的图像的高

    # （2）文件配置
    # 导入所有需要对图片文件
    imgGesture1 = cv2.imread('resource/ok.png', cv2.IMREAD_UNCHANGED)  # 手势1
    imgGesture2 = cv2.imread('resource/spider.png', cv2.IMREAD_UNCHANGED)  # 手势2
    imgGesture3 = cv2.imread('resource/gun.png', cv2.IMREAD_UNCHANGED)  # 手势3
    imgGesture4 = cv2.imread('resource/big.png', cv2.IMREAD_UNCHANGED)  # 手势1
    imgGesture5 = cv2.imread('resource/ye.png', cv2.IMREAD_UNCHANGED)  # 手势2
    back = cv2.imread('resource/back.png', cv2.IMREAD_UNCHANGED)
    # 调整size
    imgGesture1 = cv2.resize(imgGesture1, dsize=(200, 200))
    imgGesture2 = cv2.resize(imgGesture2, dsize=(200, 200))
    imgGesture3 = cv2.resize(imgGesture3, dsize=(200, 200))
    imgGesture4 = cv2.resize(imgGesture4, dsize=(200, 200))
    imgGesture5 = cv2.resize(imgGesture5, dsize=(200, 200))
    back = cv2.resize(back, dsize=(300, 300))

    speed = 6  # 图片下落速度
    add_speed = 3  # 图片生成速度
    dif = 10
    # 图片初始位置
    Gestures = []
    Gestures.append([1, 115, -200])
    last_added_time = time.time()
    last_move_time = time.time()
    # 记录是否游戏结束
    gameover = False
    score = 0  # 记录分数

    cap = cv2.VideoCapture(0)
    cap.set(3, 1281)
    cap.set(4, 720)

    changed = [0, 0, 0]
    color = (125, 0, 0)
    w, h = 427, 720
    detector = HandDetector(
        maxHands=2,
        detectionCon=0.8,
        minTrackCon=0.5)
    n = 0
    # 建立分区
    ptList = []
    ptList.append([0, 0])
    ptList.append([427, 0])
    ptList.append([427 + 427, 0])
    score = 0
    # 启动背景音乐，准备好音效
    pygame.mixer.init()
    pygame.mixer.music.load('./bgm/bgm1.mp3')
    pygame.mixer.music.play(loops=-1)
    sound2 = pygame.mixer.Sound('./bgm/enterServer.mp3')

    # 处理每一帧帧图像
    while True:
        time.sleep(0.01)
        success, img = cap.read()
        img = cv2.flip(img, flipCode=1)
        hands, img = detector.findHands(img, flipType=False)
        for index, pt in enumerate(ptList):
            if changed[index] == 1:
                color = (0, 0, 125)
            elif changed[index] == 0:
                color = (255, 125, 0)
            img = crebak(img, color, pt[0], pt[1], w, h)
        changed = [0, 0, 0]
        lmList = [0, 0, 0, 0]
        center = [0, 0, 0, 0]
        ges = [[0, 0], [0, 0], [0, 0], [0, 0]]

        if gameover:
            img = cvzone.overlayPNG(img, back, [1000, -100])
            cv2.putText(img, 'Game Over', (380, 280), cv2.FONT_HERSHEY_PLAIN, 6, (0, 255, 0), 6)
            cv2.putText(img, 'Your Score: ' + str(score), (250, 380), cv2.FONT_HERSHEY_PLAIN, 6, (0, 255, 0), 6)
            cv2.putText(img, 'Fist up to start again ' + str(score), (150, 480), cv2.FONT_HERSHEY_PLAIN, 6, (0, 255, 0), 6)
            if hands:
                n = len(hands)
                # 保存所有手的信息
                for i in range(n):
                    lmList[i] = hands[i]['lmList']
                    if ((lmList[i][8][0] > 1000) and (lmList[i][8][0] < 1280)) and (
                            (lmList[i][8][1] > 0) and (lmList[i][8][1] < 100)):

                        pygame.mixer.music.stop()
                        cap.release()
                        cv2.destroyAllWindows()
                        controller.turn_to_menu()
                        return

                    if gesture2(lmList[i]):
                        speed = 6  # 图片下落速度
                        add_speed = 3  # 图片生成速度
                        dif = 10
                        # 图片初始位置
                        Gestures = []
                        Gestures.append([1, 115, -200])
                        last_added_time = time.time()
                        last_move_time = time.time()
                        # 记录是否游戏结束
                        gameover = False
                        score = 0  # 记录分数
                        pygame.mixer.music.play(loops=-1)
                        break


            cv2.imshow('game', img)
            if cv2.waitKey(1) & 0xFF == 27:
                break
            continue
        if hands:
            n = len(hands)
            # 保存所有手的信息
            for i in range(n):
                lmList[i] = hands[i]['lmList']
                center[i] = hands[i]['center']
            # 计算并保存每个手的状态
            for i in range(n):
                for index, pt in enumerate(ptList):
                    ptx, pty = pt
                    if ptx <= center[i][0] <= ptx + w and pty <= center[i][1] <= pty + h:
                        changed[index] = 1
                        ges[i] = [index, gesture1(lmList[i])]
        current_added_time = time.time()
        if current_added_time - last_added_time >= add_speed:
            x = random.choice([1, 2, 3, 4, 5])
            y = random.choice([115, 542, 969])
            Gestures.append([x, y, -200])
            last_added_time = current_added_time

        new_gestures = []
        for gesture in Gestures:
            good = False
            for i in range(n):
                fuck = ges[i][0] * 427 + 115
                if fuck == gesture[1] and ges[i][1] == gesture[0]:
                    good = True
                else:
                    continue
            if good:
                score += 10
                sound2.play(0)
            else:
                new_gestures.append(gesture)

        Gestures = new_gestures
        current_move_time = time.time()

        if current_move_time - last_move_time > 0.01:
            for gesture in Gestures:
                if gesture[2] > 700:
                    gameover = True
                gesture[2] = gesture[2] + speed
                if gesture[0] == 1:
                    img = cvzone.overlayPNG(img, imgGesture1, [gesture[1], gesture[2]])
                elif gesture[0] == 2:
                    img = cvzone.overlayPNG(img, imgGesture2, [gesture[1], gesture[2]])
                elif gesture[0] == 3:
                    img = cvzone.overlayPNG(img, imgGesture3, [gesture[1], gesture[2]])
                elif gesture[0] == 4:
                    img = cvzone.overlayPNG(img, imgGesture4, [gesture[1], gesture[2]])
                elif gesture[0] == 5:
                    img = cvzone.overlayPNG(img, imgGesture5, [gesture[1], gesture[2]])

            last_move_time = current_move_time

        if score / dif > 3:
            dif += 10
            if speed < 20:
                speed += 2
            if add_speed > 0.5:
                add_speed -= 0.2
        str1 = 'score:' + str(int(score))
        cv2.putText(img, str1, (10, 70), cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 0), 3)
        cv2.imshow('game', img)
        if cv2.waitKey(1) & 0xFF == 27:
            break
        time.sleep(0.01)
    pygame.mixer.music.stop()
    cap.release()
    cv2.destroyAllWindows()



